package com.lineage.server.model.drop;

import com.lineage.config.ConfigAlt;
import com.lineage.config.ConfigDrop;
import com.lineage.config.ConfigGuaji;
import com.lineage.config.ConfigOther;
import com.lineage.data.event.Armortype;
import com.lineage.server.datatables.Drop_limit;
import com.lineage.server.datatables.ItemLimitTable;
import com.lineage.server.datatables.ItemMsgTable;
import com.lineage.server.datatables.ItemdropTable;
import com.lineage.server.datatables.RecordTable;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.Instance.L1PetInstance;
import com.lineage.server.model.Instance.L1SummonInstance;
import com.lineage.server.model.item.L1ItemId;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1GroundInventory;
import com.lineage.server.model.L1Inventory;
import com.lineage.server.model.L1Location;
import com.lineage.server.model.L1Object;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.types.Point;
import com.lineage.server.utils.ListMapUtil;
import com.lineage.server.utils.RandomArrayList;
import com.lineage.server.world.World;
import com.lineage.william.drop_type_armor_npc;
import com.lineage.william.drop_type_weapon_npc;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DropShare implements DropShareExecutor {
  private static final Log _log = LogFactory.getLog(DropShare.class);
  
	// 正向
	private static final byte HEADING_TABLE_X[] = { 0, 1, 1, 1, 0, -1, -1, -1 };

	private static final byte HEADING_TABLE_Y[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
  
  private static final Random _random = new Random();
  
  public void dropShare(L1NpcInstance npc, ArrayList<L1Character> acquisitorList, ArrayList<Integer> hateList) {
    DropShareR dropShareR = new DropShareR(npc, acquisitorList, hateList);
    GeneralThreadPool.get().schedule(dropShareR, 0L);
  }
  
  private class DropShareR implements Runnable {
    final L1NpcInstance _npc;
    
    final ArrayList<L1Character> _acquisitorList;
    
    final ArrayList<Integer> _hateList;
    
    private DropShareR(L1NpcInstance npc, ArrayList<L1Character> acquisitorList, ArrayList<Integer> hateList) {
      this._npc = npc;
      this._acquisitorList = acquisitorList;
      this._hateList = hateList;
    }
    
    public void run() {
      try {
        L1Inventory inventory = this._npc.getInventory();
        if (inventory != null && 
          inventory.getSize() > 0 && 
          this._acquisitorList.size() == this._hateList.size()) {
          int totalHate = 0;
          int i = this._hateList.size() - 1;
          while (i >= 0) {
            L1Character acquisitor = this._acquisitorList.get(i);
            if (ConfigAlt.AUTO_LOOT == 2 && (acquisitor instanceof com.lineage.server.model.Instance.L1SummonInstance || 
              acquisitor instanceof com.lineage.server.model.Instance.L1PetInstance)) {
              this._acquisitorList.remove(i);
              this._hateList.remove(i);
            } else if (acquisitor != null && acquisitor.getMapId() == this._npc.getMapId() && 
              acquisitor.getLocation().getTileLineDistance(
                (Point)this._npc.getLocation()) <= ConfigAlt.LOOTING_RANGE) {
              totalHate += ((Integer)this._hateList.get(i)).intValue();
            } else {
              this._acquisitorList.remove(i);
              this._hateList.remove(i);
            } 
            i--;
          } 
          L1Inventory targetInventory = null;
          Random random = new Random();
          boolean guajidrop = false;
          List<L1ItemInstance> list = inventory.getItems();
          if (list.isEmpty())
            return; 
          if (list.size() <= 0)
            return; 
          Iterator<L1ItemInstance> iterator = list.iterator();
          while (iterator.hasNext()) {
            L1ItemInstance item = iterator.next();
            int itemId = item.getItemId();
            if (item.getItem().getType2() == 0 && item.getItem().getType() == 2)
              item.setNowLighting(false); 
            if (!Drop_limit.get().checkItemIdCanDrop(itemId)) {
              targetInventory = null;
              break;
            } 
            if (this._npc.getNpcId() == 97259 && itemId == 80026) {
              equalityDrop(this._npc, this._acquisitorList, itemId);
              continue;
            } 
            if (this._npc.getNpcId() == 97258 && itemId == 80024) {
              equalityDrop(this._npc, this._acquisitorList, itemId);
              continue;
            } 
            if (this._npc.getNpcId() == 107034 && itemId == 82239) {
              equalityDrop(this._npc, this._acquisitorList, itemId);
              continue;
            } 
            if (this._npc.getNpcId() == 107035 && itemId == 82236) {
              equalityDrop(this._npc, this._acquisitorList, itemId);
              continue;
            } 
            if (this._npc.getNpcId() == 99019 && itemId == 85010) {
              equalityDrop(this._npc, this._acquisitorList, itemId);
              continue;
            } 
            if (this._npc.getNpcId() == 99012 && itemId == 56313) {
              equalityDropScreen(this._npc, itemId);
              continue;
            } 
            if ((ConfigAlt.AUTO_LOOT != 0 || itemId == 40308) && totalHate > 0) {
              int randomInt = random.nextInt(totalHate);
              int chanceHate = 0;
              long itemCount = item.getCount();
              int j = this._hateList.size() - 1;
              while (j >= 0) {
                Thread.sleep(1L);
                chanceHate += ((Integer)this._hateList.get(j)).intValue();
                if (chanceHate > randomInt) {
                  L1Character acquisitor = this._acquisitorList.get(j);
                  if (acquisitor.getInventory().checkAddItem(item, item.getCount()) != 0) {
                    item.set_showId(this._npc.get_showId());
                    L1GroundInventory l1GroundInventory = World.get().getInventory(acquisitor.getX(), 
                        acquisitor.getY(), acquisitor.getMapId());
                    l1GroundInventory.storeItem(item.getId(), item.getCount());
                    break;
                  } 

                  targetInventory = acquisitor.getInventory();
                  if (!(acquisitor instanceof L1PcInstance))
                    break; 
                  L1PcInstance player = (L1PcInstance)acquisitor;
                  if (itemId == 40308) {
                    double addadena = player.getGF();
                    if (player.getguaji_count() > 0) {
                      if (player.isActived() || player.get_followmaster() != null) {
                        itemCount = (long)((itemCount + itemCount * addadena) * 
                          ConfigGuaji.guaji_hu_adena);
                        item.setCount(itemCount);
                      } 
                    } else if (player.isActived() || 
                      player.get_followmaster() != null) {
                      itemCount = (long)((itemCount + itemCount * addadena) * 
                        ConfigGuaji.adena);
                      item.setCount(itemCount);
                    } else if (addadena > 0.0D) {
                      itemCount = (long)((itemCount + itemCount * addadena) * 0.7D);
                      item.setCount(itemCount);
                    } 
                  } 
                  if (player.isActived() && !ItemdropTable.RESTRICTIONS
                    .contains(Integer.valueOf(item.getItemId()))) {
                    guajidrop = true;
                    
    				if (guajidrop && ItemdropTable.RESTRICTIONS.contains(Integer.valueOf(item.getItemId()))) {
					continue;
				} else {
					Drop_limit.get().addCount(itemId, item.getCount());
					inventory.tradeItem(item, item.getCount(), targetInventory);
					guajidrop = false;
				}
                  } else {
                    if (ItemLimitTable.TIME
                      .get(Integer.valueOf(item.getItemId())) != null) {
                      int date = 0;
                      date = ((Integer)ItemLimitTable.TIME
                        .get(Integer.valueOf(item.getItemId()))).intValue();
                      if (date <= 0)
                        return; 
                      ItemLimitTable.get().update(item);
                      ItemLimitTable.get().load();
                    } 
                    if (Armortype.START) {
                      if (item.getItem().getType2() == 1 && 
                        item.getItem().isdropcolor() && 
                        ConfigOther.dropcolor)
                        drop_type_weapon_npc.forIntensifyArmor(player, item); 
                      if (item.getItem().getType2() == 2 && 
                        item.getItem().isdropcolor() && 
                        ConfigOther.dropcolor)
                        drop_type_armor_npc.forIntensifyArmor(player, item); 
                    } 
                    if (player.isInParty()) {
                      Object[] pcs = player.getParty().partyUsers().values()
                        .toArray();
                      if (pcs.length <= 0)
                        return; 
                      Object[] array;
                      int length = (array = pcs).length;
                      int l = 0;
                      while (l < length) {
                        Object obj = array[l];
                        if (obj instanceof L1PcInstance) {
                          L1PcInstance tgpc = (L1PcInstance)obj;
                          if (tgpc.hasSkillEffect(1689))
                            tgpc.sendPackets((ServerBasePacket)new S_ServerMessage(813, 
                                  this._npc.getNameId(), item.getLogName(), 
                                  player.getName())); 
                        } 
                        l++;
                      } 
                    } else if (player.hasSkillEffect(1690)) {
                      player.sendPackets((ServerBasePacket)new S_ServerMessage(143, 
                            this._npc.getNameId(), item.getLogName()));
                    } 
                    if (ItemMsgTable.get().contains(item.getItemId()) && 
                      player.getWeapon() != null) {
                      if (!player.isGm() && player.hasSkillEffect(1691))
                        ConfigDrop.msg(player.getName(), this._npc.getName(), 
                            item.getName(), player.getWeapon().getLogName()); 
                      RecordTable.get().recordeItemEcho(player.getName(), 
                          item.getName(), (int)item.getCount(), item.getId(), 
                          this._npc.getName(), player.getIp());
                    } 
                    break;
                  } 
                } 
                j--;
              } 
            } else {
              if (!Drop_limit.get().checkItemIdCanDrop(itemId)) {
                inventory.removeItem(item, item.getCount());
                continue;
              } 
              List<Integer> dirList = new ArrayList<>();
              int k = 0;
              while (k < 8) {
                dirList.add(Integer.valueOf(k));
                k++;
              } 
              int x = 0;
              int y = 0;
              int dir = 0;
              while (dirList.size() != 0) {
                int randomInt = random.nextInt(dirList.size());
                dir = ((Integer)dirList.get(randomInt)).intValue();
                dirList.remove(randomInt);
                x = DropShare.HEADING_TABLE_X[dir];
                y = DropShare.HEADING_TABLE_Y[dir];
                Thread.sleep(1L);
                this._npc.getMap().isPassable(this._npc.getX(), this._npc.getY(), dir, 
                    null);
              } 
              x = 0;
              y = 0;
              this._npc.getInventory().deleteItem(item);
              ListMapUtil.clear(dirList);
            } 
//			if (inventory.checkAddItem(item, item.getCount()) != 0) {
//				if (guajidrop) {
//					Drop_limit.get().addCount(itemId, item.getCount());
//					inventory.tradeItem(item, item.getCount(), targetInventory);
//					guajidrop = false;
//				} else {
//					continue;
//				}
//			}
//            else {
//				break;
//			}
//            if (guajidrop && 
//                    ItemdropTable.RESTRICTIONS.contains(Integer.valueOf(item.getItemId())))
//                    continue; 
                  Drop_limit.get().addCount(itemId, item.getCount());
                  inventory.tradeItem(item, item.getCount(), targetInventory);
//                  guajidrop = false;
          } 
          ListMapUtil.clear(list);
        } 
        return;
      } catch (Exception exception) {
      
      } finally {
        ListMapUtil.clear(this._acquisitorList);
        ListMapUtil.clear(this._hateList);
      } 
    }
    
    public void equalityDrop(L1NpcInstance npc, ArrayList<?> recipientList, int itemId) {
      L1Inventory inventory = npc.getInventory();
      if (inventory.getSize() == 0)
        return; 
      L1Location pt = npc.getLocation();
      int i = recipientList.size() - 1;
      while (i >= 0) {
        L1Character recipient = (L1Character)recipientList.get(i);
        if (recipient instanceof com.lineage.server.model.Instance.L1SummonInstance || recipient instanceof com.lineage.server.model.Instance.L1PetInstance) {
          recipientList.remove(i);
        } else if (recipient == null) {
          recipientList.remove(i);
        } else if (npc.getMapId() != recipient.getMapId()) {
          recipientList.remove(i);
        } else if (!pt.isInScreen((Point)recipient.getLocation()) && npc.getNpcId() != 99019) {
          recipientList.remove(i);
        } 
        i--;
      } 
      Iterator<L1ItemInstance> iterator = inventory.getItems().iterator();
      while (iterator.hasNext()) {
        L1ItemInstance drop = iterator.next();
        int j = recipientList.size() - 1;
        while (j >= 0) {
          L1PcInstance pc = (L1PcInstance)recipientList.get(j);
          if (drop.getItemId() == itemId)
            if (pc.getInventory().checkAddItem(drop, drop.getCount()) == 0) {
              pc.getInventory().storeItem(drop.getItemId(), drop.getCount());
              if (pc.isInParty()) {
                Object[] pcs = pc.getParty().partyUsers().values().toArray();
                if (pcs.length <= 0)
                  return; 
                Object[] array;
                int length = (array = pcs).length;
                int k = 0;
                while (k < length) {
                  Object obj = array[k];
                  if (obj instanceof L1PcInstance) {
                    L1PcInstance tgpc = (L1PcInstance)obj;
                    tgpc.sendPackets((ServerBasePacket)new S_ServerMessage(813, this._npc.getNameId(), 
                          drop.getLogName(), pc.getName()));
                  } 
                  k++;
                } 
              } else {
                pc.sendPackets((ServerBasePacket)new S_ServerMessage(143, this._npc.getNameId(), drop.getLogName()));
              } 
            } else {
              drop.set_showId(npc.get_showId());
              L1GroundInventory l1GroundInventory = World.get().getInventory(pc.getX(), pc.getY(), pc.getMapId());
              l1GroundInventory.storeItem(drop.getItemId(), drop.getCount());
            }  
          j--;
        } 
      } 
    }
    
    public void equalityDropScreen(L1NpcInstance npc, int itemId) {
      L1Inventory inventory = npc.getInventory();
      if (inventory.getSize() == 0)
        return; 
      ArrayList<L1PcInstance> recipientList = World.get().getVisiblePlayer((L1Object)npc);
      Iterator<L1ItemInstance> iterator = inventory.getItems().iterator();
      while (iterator.hasNext()) {
        L1ItemInstance drop = iterator.next();
        int i = recipientList.size() - 1;
        while (i >= 0) {
          L1PcInstance pc = recipientList.get(i);
          if (drop.getItemId() == itemId)
            if (pc.getInventory().checkAddItem(drop, drop.getCount()) == 0) {
              pc.getInventory().storeItem(drop.getItemId(), drop.getCount());
              if (pc.isInParty()) {
                Object[] pcs = pc.getParty().partyUsers().values().toArray();
                if (pcs.length <= 0)
                  return; 
                Object[] array;
                int length = (array = pcs).length;
                int j = 0;
                while (j < length) {
                  Object obj = array[j];
                  if (obj instanceof L1PcInstance) {
                    L1PcInstance tgpc = (L1PcInstance)obj;
                    tgpc.sendPackets((ServerBasePacket)new S_ServerMessage(813, this._npc.getNameId(), 
                          drop.getLogName(), pc.getName()));
                  } 
                  j++;
                } 
              } else {
                pc.sendPackets((ServerBasePacket)new S_ServerMessage(143, this._npc.getNameId(), drop.getLogName()));
              } 
            } else {
              drop.set_showId(npc.get_showId());
              L1GroundInventory l1GroundInventory = World.get().getInventory(pc.getX(), pc.getY(), pc.getMapId());
              l1GroundInventory.storeItem(drop.getItemId(), drop.getCount());
            }  
          i--;
        } 
      } 
    }
  }
}

  
